//
//  nbjAppDelegate.m
//  nbj
//
//  Created by Francois Proulx on 09-09-20.
//  Copyright __MyCompanyName__ 2009. All rights reserved.
//

#import "nbjAppDelegate.h"

#import "FlurryAPI.h"
#import "ASIHTTPRequest.h"
#import "Reachability.h"
#import "NBJRootViewController.h"

@interface nbjAppDelegate()

@property (nonatomic, readonly) NSString *persistentStorePath;
@property (nonatomic, assign, readonly) BOOL internetConnectionAvailable;
@property (nonatomic, retain) NSString *apnsDeviceToken;

@end

@implementation nbjAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize rootViewController;

@synthesize apnsDeviceToken;

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{   
	// Register with Flurry
	[FlurryAPI startSessionWithLocationServices:@"9ATJ7Y2TDKLDQ51ZUK2J"];
	
	//Register for push notifications
	[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
	 (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
	
	// Temporarly save most recent push payload for later use
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	NSDictionary *recentPushPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
	if(recentPushPayload) {
		[userDefaults setObject:recentPushPayload forKey:NBJAPNSLastPushPayload];
		[userDefaults setBool:YES forKey:NBJAPNSForcedUpdate];
	} else {
		[userDefaults setBool:NO forKey:NBJAPNSForcedUpdate];
	}
	
	// Inject core data context and display GUI
	rootViewController.mainManagedObjectContext = self.mainManagedObjectContext;
	[window addSubview:navigationController.view];
	[window makeKeyAndVisible];
	
	return YES;
}

- (void) applicationWillTerminate:(UIApplication *)application 
{	
    NSError *error = nil;
    if (mainManagedObjectContext != nil) {
        if ([mainManagedObjectContext hasChanges] && ![mainManagedObjectContext save:&error]) {
			NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        } 
    }
}

#pragma mark -
#pragma mark APNS Push notifications

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)rawDeviceToken 
{
	const unsigned *tokenBytes = [rawDeviceToken bytes];
	self.apnsDeviceToken = [NSString stringWithFormat:@"%08X%08X%08X%08X%08X%08X%08X%08X",
							ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
							ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
							ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
	NSLog(@"APNS: Received device token from Apple %@", self.apnsDeviceToken);
	
	NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
	NSString *urlString = [NSString stringWithFormat:@"%@%@/", @"https://go.urbanairship.com/api/device_tokens/", self.apnsDeviceToken];
	NSURL *url = [NSURL URLWithString:urlString];
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
	request.delegate = self;
	request.requestMethod = @"PUT";
	request.username = NBJUrbanAirshipApplicationKey;
	request.password = NBJUrbanAirshipApplicationSecret;
	[request setDidFinishSelector:@selector(successMethod:)];
	[request setDidFailSelector:@selector(requestWentWrong:)];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[queue addOperation:request];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error 
{
	NSLog(@"APNS: Failed to register with error: %@", error);
}

- (void)successMethod:(ASIHTTPRequest *) request 
{
	NSLog(@"APNS: Device token succesfully sent to Urban Airship");
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	[userDefaults setValue:self.apnsDeviceToken forKey:NBJUrbanAirshipRegisteredDeviceTokenUserDefaultsKey];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void)requestWentWrong:(ASIHTTPRequest *)request 
{
	NSError *error = [request error];
	NSLog(@"APNS: NSError query result: %@", error);
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
{
	NSString *message =  [[userInfo objectForKey: @"aps"] objectForKey: @"alert"];
	NSLog(@"APNS: Received message %@", message);
	UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"NBJ" 
													message:message 
												   delegate:nil 
										  cancelButtonTitle:@"OK" 
										  otherButtonTitles:nil];
    [alert show];
    [alert release];
	
	// Save state
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	[userDefaults setObject:userInfo forKey:NBJAPNSLastPushPayload];
	[userDefaults setBool:YES forKey:NBJAPNSForcedUpdate];
}

#pragma mark -
#pragma mark Network Reachability

- (BOOL) internetConnectionAvailable
{
	NetworkStatus status = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];
	return status != NotReachable;
}

#pragma mark -
#pragma mark Core Data stack

- (NSManagedObjectContext *) mainManagedObjectContext 
{	
    if (mainManagedObjectContext != nil) {
        return mainManagedObjectContext;
    }
	
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        mainManagedObjectContext = [[NSManagedObjectContext alloc] init];
        [mainManagedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return mainManagedObjectContext;
}

- (NSManagedObjectModel *) managedObjectModel 
{
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
	
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator 
{	
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
	
    NSURL *storeUrl = [NSURL fileURLWithPath:self.persistentStorePath];
	
	NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
		NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }
	
    return persistentStoreCoordinator;
}


#pragma mark -
#pragma mark Application's Documents directory

- (NSString *) applicationDocumentsDirectory 
{
	return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

- (NSString *) persistentStorePath
{
	return [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"nbj.sqlite"];
}

#pragma mark -
#pragma mark Memory management

- (void)dealloc 
{
	[window release];
	[navigationController release];
	[rootViewController release];
	
    [mainManagedObjectContext release];
    [managedObjectModel release];
    [persistentStoreCoordinator release];
	
	self.apnsDeviceToken = nil;
	
	[super dealloc];
}


@end

